{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1495814 entries, 0 to 1495813\n",
      "Data columns (total 22 columns):\n",
      "Unnamed: 0        1495814 non-null int64\n",
      "Unnamed: 0.1      1495814 non-null int64\n",
      "year              1495814 non-null int64\n",
      "month             1495814 non-null int64\n",
      "day               1495814 non-null int64\n",
      "time_cat          1495814 non-null object\n",
      "time_num          1495814 non-null float64\n",
      "time_cos          1495814 non-null float64\n",
      "time_sin          1495814 non-null float64\n",
      "day_cat           1495814 non-null object\n",
      "day_num           1495814 non-null float64\n",
      "day_cos           1495814 non-null float64\n",
      "day_sin           1495814 non-null float64\n",
      "weekend           1495814 non-null int64\n",
      "x_start           1495814 non-null float64\n",
      "y_start           1495814 non-null float64\n",
      "z_start           1495814 non-null float64\n",
      "location_start    1495814 non-null object\n",
      "location_end      1495814 non-null object\n",
      "end_lat           1495814 non-null float64\n",
      "end_lon           1495814 non-null float64\n",
      "mon_num           1495814 non-null float64\n",
      "dtypes: float64(12), int64(6), object(4)\n",
      "memory usage: 251.1+ MB\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "Df = pd.read_csv('featured-dataset_new_KNN.csv',low_memory=False)\n",
    "Df['mon_num'] = Df['month'].apply(lambda row: row/12.)\n",
    "Df.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import geohash"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Unnamed: 0.1</th>\n",
       "      <th>year</th>\n",
       "      <th>month</th>\n",
       "      <th>day</th>\n",
       "      <th>time_cat</th>\n",
       "      <th>time_num</th>\n",
       "      <th>time_cos</th>\n",
       "      <th>time_sin</th>\n",
       "      <th>day_cat</th>\n",
       "      <th>day_num</th>\n",
       "      <th>...</th>\n",
       "      <th>day_sin</th>\n",
       "      <th>weekend</th>\n",
       "      <th>x_start</th>\n",
       "      <th>y_start</th>\n",
       "      <th>z_start</th>\n",
       "      <th>location_start</th>\n",
       "      <th>location_end</th>\n",
       "      <th>end_lat</th>\n",
       "      <th>end_lon</th>\n",
       "      <th>mon_num</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>2018</td>\n",
       "      <td>1</td>\n",
       "      <td>20</td>\n",
       "      <td>10:0</td>\n",
       "      <td>0.425694</td>\n",
       "      <td>-0.892979</td>\n",
       "      <td>0.450098</td>\n",
       "      <td>Saturday</td>\n",
       "      <td>0.775099</td>\n",
       "      <td>...</td>\n",
       "      <td>-0.987591</td>\n",
       "      <td>1</td>\n",
       "      <td>-0.055090</td>\n",
       "      <td>0.712922</td>\n",
       "      <td>0.699076</td>\n",
       "      <td>wqp25w569</td>\n",
       "      <td>wqp25tkvt</td>\n",
       "      <td>33.779811</td>\n",
       "      <td>111.605885</td>\n",
       "      <td>0.083333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>2018</td>\n",
       "      <td>2</td>\n",
       "      <td>12</td>\n",
       "      <td>17:30</td>\n",
       "      <td>0.736111</td>\n",
       "      <td>-0.087156</td>\n",
       "      <td>-0.996195</td>\n",
       "      <td>Monday</td>\n",
       "      <td>0.105159</td>\n",
       "      <td>...</td>\n",
       "      <td>0.613695</td>\n",
       "      <td>0</td>\n",
       "      <td>0.746854</td>\n",
       "      <td>-0.615984</td>\n",
       "      <td>-0.250546</td>\n",
       "      <td>ww4nj3h7m</td>\n",
       "      <td>ww4nj3u7r</td>\n",
       "      <td>34.814875</td>\n",
       "      <td>115.549374</td>\n",
       "      <td>0.166667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>2018</td>\n",
       "      <td>2</td>\n",
       "      <td>13</td>\n",
       "      <td>14:45</td>\n",
       "      <td>0.619444</td>\n",
       "      <td>-0.731354</td>\n",
       "      <td>-0.681998</td>\n",
       "      <td>Tuesday</td>\n",
       "      <td>0.231349</td>\n",
       "      <td>...</td>\n",
       "      <td>0.993142</td>\n",
       "      <td>0</td>\n",
       "      <td>0.762286</td>\n",
       "      <td>-0.641939</td>\n",
       "      <td>-0.082670</td>\n",
       "      <td>ww4jj4hfq</td>\n",
       "      <td>ww4nj9e9j</td>\n",
       "      <td>34.813136</td>\n",
       "      <td>115.559243</td>\n",
       "      <td>0.166667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>2018</td>\n",
       "      <td>2</td>\n",
       "      <td>13</td>\n",
       "      <td>17:15</td>\n",
       "      <td>0.724306</td>\n",
       "      <td>-0.160743</td>\n",
       "      <td>-0.986996</td>\n",
       "      <td>Tuesday</td>\n",
       "      <td>0.246329</td>\n",
       "      <td>...</td>\n",
       "      <td>0.999734</td>\n",
       "      <td>0</td>\n",
       "      <td>0.740919</td>\n",
       "      <td>-0.620137</td>\n",
       "      <td>-0.257816</td>\n",
       "      <td>ww4nj4rph</td>\n",
       "      <td>ww4nj9e9h</td>\n",
       "      <td>34.813141</td>\n",
       "      <td>115.559217</td>\n",
       "      <td>0.166667</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>2018</td>\n",
       "      <td>2</td>\n",
       "      <td>13</td>\n",
       "      <td>18:0</td>\n",
       "      <td>0.754167</td>\n",
       "      <td>0.026177</td>\n",
       "      <td>-0.999657</td>\n",
       "      <td>Tuesday</td>\n",
       "      <td>0.250595</td>\n",
       "      <td>...</td>\n",
       "      <td>0.999993</td>\n",
       "      <td>0</td>\n",
       "      <td>0.752481</td>\n",
       "      <td>-0.608090</td>\n",
       "      <td>-0.252980</td>\n",
       "      <td>ww4nj9edj</td>\n",
       "      <td>ww4muu95u</td>\n",
       "      <td>34.786126</td>\n",
       "      <td>115.874361</td>\n",
       "      <td>0.166667</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 21 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "   Unnamed: 0.1  year  month  day time_cat  time_num  time_cos  time_sin  \\\n",
       "0             0  2018      1   20     10:0  0.425694 -0.892979  0.450098   \n",
       "1             1  2018      2   12    17:30  0.736111 -0.087156 -0.996195   \n",
       "2             2  2018      2   13    14:45  0.619444 -0.731354 -0.681998   \n",
       "3             3  2018      2   13    17:15  0.724306 -0.160743 -0.986996   \n",
       "4             4  2018      2   13     18:0  0.754167  0.026177 -0.999657   \n",
       "\n",
       "    day_cat   day_num    ...      day_sin  weekend   x_start   y_start  \\\n",
       "0  Saturday  0.775099    ...    -0.987591        1 -0.055090  0.712922   \n",
       "1    Monday  0.105159    ...     0.613695        0  0.746854 -0.615984   \n",
       "2   Tuesday  0.231349    ...     0.993142        0  0.762286 -0.641939   \n",
       "3   Tuesday  0.246329    ...     0.999734        0  0.740919 -0.620137   \n",
       "4   Tuesday  0.250595    ...     0.999993        0  0.752481 -0.608090   \n",
       "\n",
       "    z_start  location_start location_end    end_lat     end_lon   mon_num  \n",
       "0  0.699076       wqp25w569    wqp25tkvt  33.779811  111.605885  0.083333  \n",
       "1 -0.250546       ww4nj3h7m    ww4nj3u7r  34.814875  115.549374  0.166667  \n",
       "2 -0.082670       ww4jj4hfq    ww4nj9e9j  34.813136  115.559243  0.166667  \n",
       "3 -0.257816       ww4nj4rph    ww4nj9e9h  34.813141  115.559217  0.166667  \n",
       "4 -0.252980       ww4nj9edj    ww4muu95u  34.786126  115.874361  0.166667  \n",
       "\n",
       "[5 rows x 21 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Df = Df.drop(Df.columns[0],axis=1)\n",
    "Df.head(5)\n",
    "# year mon day time_cat time_num time_cos time_sin day_cat day_num day_cos day_sin weekend x_sta y_sta z_sta lostart loend\n",
    "# 0    1   2   3         4        5        6        7       8       9       10     11      12     13   14     15      16\n",
    "# start_lat start_lon end_lat end_lon\n",
    "#  17        18        19      20 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1495814, 21)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Df.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "columns_all_features = Df.columns\n",
    "columns_X = ['day_num', 'mon_num', 'x_start', 'y_start', 'z_start']\n",
    "columns_y = ['end_lat', 'end_lon']\n",
    "testDf_1 = Df.sample(frac=0.5)\n",
    "testDf_2 = Df.sample(frac=0.5)\n",
    "testDf_3 = Df.sample(frac=0.5)\n",
    "X_1 = testDf_1[columns_X]\n",
    "y_1 = testDf_1[columns_y]\n",
    "X_2 = testDf_2[columns_X]\n",
    "y_2 = testDf_2[columns_y]\n",
    "X_3 = testDf_3[columns_X]\n",
    "y_3 = testDf_3[columns_y]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X1_train, X1_test, y1_train, y1_test = train_test_split(X_1, y_1, test_size=0.2)\n",
    "X2_train, X2_test, y2_train, y2_test = train_test_split(X_2, y_2, test_size=0.2)\n",
    "X3_train, X3_test, y3_train, y3_test = train_test_split(X_3, y_3, test_size=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "X1: (747907, 5)\n",
      "y1: (747907, 2)\n",
      "X1_train: (598325, 5)\n",
      "y1_train: (598325, 2)\n",
      "X1_test: (149582, 5)\n",
      "y1_test: (149582, 2)\n",
      "X2: (747907, 5)\n",
      "y2: (747907, 2)\n",
      "X2_train: (598325, 5)\n",
      "y2_train: (598325, 2)\n",
      "X2_test: (149582, 5)\n",
      "y2_test: (149582, 2)\n"
     ]
    }
   ],
   "source": [
    "print ('X1: ({}, {})'.format(*X_1.shape))\n",
    "print ('y1: ({}, {})'.format(*y_1.shape))\n",
    "print ('X1_train: ({}, {})'.format(*X1_train.shape))\n",
    "print ('y1_train: ({}, {})'.format(*y1_train.shape))\n",
    "print ('X1_test: ({}, {})'.format(*X1_test.shape))\n",
    "print ('y1_test: ({}, {})'.format(*y1_test.shape))\n",
    "print ('X2: ({}, {})'.format(*X_2.shape))\n",
    "print ('y2: ({}, {})'.format(*y_2.shape))\n",
    "print ('X2_train: ({}, {})'.format(*X2_train.shape))\n",
    "print ('y2_train: ({}, {})'.format(*y2_train.shape))\n",
    "print ('X2_test: ({}, {})'.format(*X2_test.shape))\n",
    "print ('y2_test: ({}, {})'.format(*y2_test.shape))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.ensemble import RandomForestRegressor\n",
    "from sklearn.metrics import mean_squared_error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 5 folds for each of 1 candidates, totalling 5 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Done   2 out of   5 | elapsed:  4.5min remaining:  6.7min\n",
      "[Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:  5.3min finished\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,\n",
      "           max_features='auto', max_leaf_nodes=None,\n",
      "           min_impurity_decrease=0.0, min_impurity_split=None,\n",
      "           min_samples_leaf=1, min_samples_split=5,\n",
      "           min_weight_fraction_leaf=0.0, n_estimators=25, n_jobs=1,\n",
      "           oob_score=False, random_state=None, verbose=0, warm_start=False)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "# Set the parameters by cross-validation\n",
    "tuned_parameters = {'n_estimators': [25], 'max_depth': [None], 'min_samples_split': [5]}\n",
    "\n",
    "\n",
    "# clf = ensemble.RandomForestRegressor(n_estimators=500, n_jobs=1, verbose=1)\n",
    "gridCV = GridSearchCV(RandomForestRegressor(), tuned_parameters, cv=5, n_jobs=-1, verbose=1)\n",
    "gridCV.fit(X1_train, y1_train)\n",
    "print (gridCV.best_estimator_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " R^2 (train) = 0.973379, R^2 (valid) = 0.889203, RMSE (train) = 1.194192, RMSE (valid) = 2.431386\n"
     ]
    }
   ],
   "source": [
    "reg = gridCV.best_estimator_\n",
    "training_accuracy = reg.score(X1_train, y1_train)\n",
    "valid_accuracy = reg.score(X1_test, y1_test)\n",
    "rmsetrain = np.sqrt(mean_squared_error(reg.predict(X1_train),y1_train))\n",
    "rmsevalid = np.sqrt(mean_squared_error(reg.predict(X1_test),y1_test))\n",
    "print (\" R^2 (train) = %0.6f, R^2 (valid) = %0.6f, RMSE (train) = %0.6f, RMSE (valid) = %0.6f\" % (training_accuracy, valid_accuracy, rmsetrain, rmsevalid))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['conbinRF01_1106.pkl']"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.externals import joblib\n",
    "joblib.dump(reg, 'conbinRF01_1106.pkl') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 5 folds for each of 1 candidates, totalling 5 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Done   2 out of   5 | elapsed:  9.9min remaining: 14.8min\n",
      "[Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed: 10.4min finished\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,\n",
      "           max_features='auto', max_leaf_nodes=None,\n",
      "           min_impurity_decrease=0.0, min_impurity_split=None,\n",
      "           min_samples_leaf=1, min_samples_split=5,\n",
      "           min_weight_fraction_leaf=0.0, n_estimators=25, n_jobs=1,\n",
      "           oob_score=False, random_state=None, verbose=0, warm_start=False)\n",
      " R^2 (train) = 0.973326, R^2 (valid) = 0.892392, RMSE (train) = 1.195899, RMSE (valid) = 2.396623\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['conbinRF02_1106.pkl']"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridCV.fit(X2_train, y2_train)\n",
    "print (gridCV.best_estimator_)\n",
    "reg = gridCV.best_estimator_\n",
    "training_accuracy = reg.score(X2_train, y2_train)\n",
    "valid_accuracy = reg.score(X2_test, y2_test)\n",
    "rmsetrain = np.sqrt(mean_squared_error(reg.predict(X2_train),y2_train))\n",
    "rmsevalid = np.sqrt(mean_squared_error(reg.predict(X2_test),y2_test))\n",
    "print (\" R^2 (train) = %0.6f, R^2 (valid) = %0.6f, RMSE (train) = %0.6f, RMSE (valid) = %0.6f\" % (training_accuracy, valid_accuracy, rmsetrain, rmsevalid))\n",
    "joblib.dump(reg, 'conbinRF02_1106.pkl') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 5 folds for each of 1 candidates, totalling 5 fits\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=-1)]: Done   2 out of   5 | elapsed: 10.3min remaining: 15.5min\n",
      "[Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed: 11.3min finished\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,\n",
      "           max_features='auto', max_leaf_nodes=None,\n",
      "           min_impurity_decrease=0.0, min_impurity_split=None,\n",
      "           min_samples_leaf=1, min_samples_split=5,\n",
      "           min_weight_fraction_leaf=0.0, n_estimators=25, n_jobs=1,\n",
      "           oob_score=False, random_state=None, verbose=0, warm_start=False)\n",
      " R^2 (train) = 0.973886, R^2 (valid) = 0.890960, RMSE (train) = 1.182947, RMSE (valid) = 2.418690\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['conbinRF03_1106.pkl']"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gridCV.fit(X3_train, y3_train)\n",
    "print (gridCV.best_estimator_)\n",
    "reg = gridCV.best_estimator_\n",
    "training_accuracy = reg.score(X3_train, y3_train)\n",
    "valid_accuracy = reg.score(X3_test, y3_test)\n",
    "rmsetrain = np.sqrt(mean_squared_error(reg.predict(X3_train),y3_train))\n",
    "rmsevalid = np.sqrt(mean_squared_error(reg.predict(X3_test),y3_test))\n",
    "print (\" R^2 (train) = %0.6f, R^2 (valid) = %0.6f, RMSE (train) = %0.6f, RMSE (valid) = %0.6f\" % (training_accuracy, valid_accuracy, rmsetrain, rmsevalid))\n",
    "joblib.dump(reg, 'conbinRF03_1106.pkl') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "importances = reg.feature_importances_\n",
    "std = np.std([tree.feature_importances_ for tree in reg.estimators_],\n",
    "             axis=0)\n",
    "indices = np.argsort(importances)[::-1]\n",
    "\n",
    "# Print the feature ranking\n",
    "print(\"Feature ranking:\")\n",
    "\n",
    "for f in range(X.shape[1]):\n",
    "    print(\"%d. feature %d (%f)\" % (f + 1, indices[f], importances[indices[f]]))\n",
    "\n",
    "# Plot the feature importances of the forest\n",
    "feature_names = X_test.columns\n",
    "plt.figure()\n",
    "plt.title(\"Feature importances\")\n",
    "plt.bar(range(X_test.shape[1]), importances[indices],\n",
    "       color=\"r\", yerr=std[indices], align=\"center\")\n",
    "plt.xticks(range(X_test.shape[1]), feature_names)\n",
    "plt.xlim([-1, X_test.shape[1]])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sampleds = pd.DataFrame(Df, columns=(columns_X + columns_y))\n",
    "sampleds = sampleds.sample(10)\n",
    "sampleds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = reg.predict(sampleds.iloc[:,:-2])\n",
    "y_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.externals import joblib\n",
    "joblib.dump(reg, 'random_forest_model_1151724.pkl') "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
